<!DOCTYPE html>
<html lang="zh_cn">

<head>
	<meta charset="UTF-8">
	<title>request</title>
	<link href="https://js.588ku.com/activity/20231024/images/vip_company_icon.png" rel="icon">
	<style>
		body {
			max-width: 800px;
			margin: 0 auto;
			padding: 20px;
			font-family: Arial, sans-serif;
		}

		.section {
			margin: 20px 0;
			padding: 15px;
			border: 1px solid #ddd;
			border-radius: 5px;
		}

		.section-title {
			font-size: 18px;
			font-weight: bold;
			margin-bottom: 15px;
			color: #333;
		}

		button {
			background: #4CAF50;
			color: white;
			border: none;
			padding: 8px 15px;
			border-radius: 4px;
			cursor: pointer;
			margin: 5px;
			transition: background 0.3s;
		}

		button:hover {
			background: #45a049;
		}

		label {
			cursor: pointer;
		}

		input[type="file"] {
			display: none;
		}
	</style>
</head>

<body>
	<div class="section">
		<div class="section-title">基础请求</div>
		<button id="postJson">POST-JSON-JSON</button>
	</div>

	<div class="section">
		<div class="section-title">上传下载</div>
		<button>
			<label for="uploadBinary">POST-BINARY-JSON
				<input type="file" name="file" id="uploadBinary" hidden>
			</label>
		</button>
		<button>
			<label for="uploadFormData">POST-FORM_DATA-JSON
				<input type="file" name="file" id="uploadFormData" hidden>
			</label>
		</button>
		<button id="streamingFile">STREAM-READ-DATA</button>
		<button id="clearAllFile">CLEAR-ALL-FILES</button>
	</div>

	<div class="section">
		<div class="section-title">WebSocket通信</div>
		<button id="connectWebsocket">连接websocket</button>
		<button id="sendMessageByWebsocket">发送websocket消息</button>
		<button id="sendFileByWebsocket">发送websocket文件</button>
		<button id="closeWebsocket">断开websocket</button>
	</div>
</body>

</html>
<script>
	const $ = (selector) => document.querySelector(selector);
	$('#postJson').onclick = () => {
		fetch('/json', {
			method: "POST",
			headers: { "Content-Type": "application/json" },
			body: JSON.stringify({ type: "json" })
		});
	};
	$('#uploadBinary').onchange = (e) => {
		let file = e.target.files[0];
		file.arrayBuffer().then(arrayBuffer => {
			fetch('/binaryUpload', {
				method: 'POST',
				headers: {
					'Content-Type': 'application/octet-stream',
					'x-ext': file.name.split('.').pop(),
				},
				body: arrayBuffer,
			});
		});
	};
	$('#uploadFormData').onchange = (e) => {
		let file = e.target.files[0];
		let formData = new FormData();
		formData.append('name', 'hyx');
		formData.append('file', file, file.name);
		fetch('/formDataUpload', {
			method: 'POST',
			body: formData,
		});
	};
	$('#streamingFile').onclick = async () => {
		const response = await fetch('/largeFile');
		// 创建一个可写入的流
		const fileHandle = await window.showSaveFilePicker({
			suggestedName: 'largeFile.txt'
		});
		const writableStream = await fileHandle.createWritable();

		// 逐步读取数据并写入文件
		const reader = response.body.getReader();
		// 创建解码器
		const decoder = new TextDecoder('utf-8', { stream: true });
		while (true) {
			const { done, value } = await reader.read();
			if (done) break;
			// 将 Uint8Array 转换为字符串
			const text = decoder.decode(value);
			console.log('读取到数据:', text);
			// 将数据写入文件
			await writableStream.write(value);
		}
		// 关闭文件流 
		await writableStream.close();
		console.log('文件下载完成！');
	};
	$('#clearAllFile').onclick = async () => {
		let response = await fetch('', { method: 'DELETE' });
	};
	$('#connectWebsocket').onclick = () => {
		if (window.ws) return;
		//第二个参数: 子协议;提交给服务端,可以是字符串,也可以是字符串数组
		//子协议可以不传,但如果传了服务端必须从中选择一个,否则无法连接
		window.ws = new WebSocket('ws://' + location.host, ['hyx', 'jyb']);
		//readyState返回当前 WebSocket 的链接状态，只读。 0:正在链接中;1:已经链接并且可以通讯;2:连接正在关闭;3:连接已关闭或者没有链接成功。
		console.log(ws.readyState);
		ws.onopen = (e) => {
			//ws.protocol 属性获取服务端选择的子协议。
			console.log('clientOpen:protocol=', ws.protocol);
			$('#sendMessageByWebsocket').onclick = () => {
				ws.send(ws.protocol + '客户端发送的消息');
				//bufferedAmount 返回已经被send()方法放入队列中但还没有被发送到网络中的数据的字节数。一旦队列中的所有数据被发送至网络，则该属性值将被重置为 0。
				console.log('待发送', ws.bufferedAmount);
				setTimeout(() => {
					console.log('待发送', ws.bufferedAmount);
				}, 100);
			};
			$('#sendFileByWebsocket').onclick = () => {
				const fileInput = document.createElement('input');
				fileInput.type = 'file';
				fileInput.onchange = async () => {
					let buffer = await fileInput.files[0].arrayBuffer();
					ws.send(buffer);
					console.log(ws.binaryType);
				};
				fileInput.click();
			};
			$('#closeWebsocket').onclick = () => {
				//关闭websocket连接,给服务端发一个opcode为8的websocket帧
				ws.close();
				window.ws = null;
			};
			ws.onmessage = (e) => {
				console.log('message', e);
			};
			ws.onclose = (e) => {
				console.log('close', e);
			};
			ws.onerror = (e) => {
				console.log('error', e);
			};
		};
	};

</script>